package com.weijian.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weijian.common.BaseContext;
import com.weijian.common.exception.ServiceException;
import com.weijian.dal.dto.OrderDetailDTO;
import com.weijian.dal.dto.OrderFormDTO;
import com.weijian.dal.entity.Item;
import com.weijian.dal.entity.Order;
import com.weijian.dal.entity.OrderDetail;
import com.weijian.dal.enums.OrderStatus;
import com.weijian.dal.vo.OrderStatisticsVO;
import com.weijian.mapper.OrderMapper;
import com.weijian.service.ItemService;
import com.weijian.service.OrderDetailService;
import com.weijian.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 服务实现类
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    private final ItemService itemService;

    private final OrderDetailService detailService;

    private final OrderMapper orderMapper;

    // TODO
    @Override
    @Transactional
    public Long createOrder(OrderFormDTO orderFormDTO) {
        // 1.订单数据
        Order order = new Order();
        // 1.1.查询商品
        List<OrderDetailDTO> detailDTOS = orderFormDTO.getDetails();
        // 1.2.获取商品id和数量的Map
        Map<Long, Integer> itemNumMap = detailDTOS.stream()
                .collect(Collectors.toMap(OrderDetailDTO::getItemId, OrderDetailDTO::getNum));
        Set<Long> itemIds = itemNumMap.keySet();
        // 1.3.查询商品
        List<Item> items = itemService.listByIds(itemIds);
        if (items == null || items.size() < itemIds.size()) {
            throw new ServiceException(401, "商品不存在");
        }
        // 1.4.基于商品价格、购买数量计算商品总价：totalFee
        int total = 0;
        for (Item item : items) {
            total += item.getPrice() * itemNumMap.get(item.getId());
        }
        // 使用雪花算法生成唯一订单号
        long orderNumber = IdUtil.getSnowflake(1, 1).nextId();
        order.setNumber(String.valueOf(orderNumber));
        order.setTotalFee(total);
        // 1.5.其它属性
        order.setAddressId(orderFormDTO.getAddressId());
        order.setPaymentType(orderFormDTO.getPaymentType());
        order.setUserId(BaseContext.getCurrentId());
        order.setStatus(OrderStatus.PENDING_PAYMENT.value);
        // 1.6.将Order写入数据库order表中
        try {
            save(order);
        } catch (Exception e) {
            log.error("保存订单失败", e);
            throw new RuntimeException(e);
        }
        // 2.保存订单详情
        List<OrderDetail> details = buildDetails(order.getId(), items, itemNumMap);
        detailService.saveBatch(details);
        return order.getId();
    }

    @Override
    public void updateOrderStatus(Long orderId, Integer status) {
        Order order = getById(orderId);
        switch (status) {
            case 0:
                order.setCreateTime(LocalDateTime.now());
                break;
            case 1:
                order.setPayTime(LocalDateTime.now());
                break;
            case 2:
                break;
            case 3:
                order.setCloseTime(LocalDateTime.now());
                break;
            case 4:
                order.setEndTime(LocalDateTime.now());
                break;
            default:
                throw new ServiceException(401, "订单状态错误");
        }
        order.setStatus(status);
        updateById(order);
    }

    @Override
    public OrderStatisticsVO statistics() {
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        Map<Integer, Long> map = new HashMap<>();
        try {
            List<Map<String, Object>> result = orderMapper.countOrdersByStatus();
            if (result != null) {
                map = result.stream()
                        .collect(Collectors.toMap(
                                m -> ((Number) m.get("status")).intValue(),
                                m -> ((Number) m.get("count")).longValue()
                        ));
            }
        } catch (Exception e) {
            log.error("统计订单失败", e);
            throw new RuntimeException(e);
        }
        log.info("统计订单结果：{}", map);
        orderStatisticsVO.setPendingPayment(map.get(OrderStatus.PENDING_PAYMENT.value));
        orderStatisticsVO.setPendingAcceptance(map.get(OrderStatus.PENDING_ACCEPTANCE.value));
        orderStatisticsVO.setPendingDelivery(map.get(OrderStatus.DELIVERY.value));
        orderStatisticsVO.setCompleted(map.get(OrderStatus.COMPLETED.value));
        orderStatisticsVO.setCanceled(map.get(OrderStatus.CANCELED.value));

        return orderStatisticsVO;
    }

    private List<OrderDetail> buildDetails(Long orderId, List<Item> items, Map<Long, Integer> numMap) {
        List<OrderDetail> details = new ArrayList<>(items.size());
        for (Item item : items) {
            OrderDetail detail = new OrderDetail();
            detail.setName(item.getName());
            detail.setPrice(item.getPrice());
            detail.setNum(numMap.get(item.getId()));
            detail.setItemId(item.getId());
            detail.setImage(item.getImage());
            detail.setOrderId(orderId);
            details.add(detail);
        }
        return details;
    }
}
